package pers.vic.boot.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

/** 
 * @description: 
 * @author: Vic.xu
 * @date: 2019年11月15日 下午5:40:53
 */
public class JsonUtil {

	public static ObjectMapper objectMapper = new ObjectMapper();
	
	static {
		//  空属性不序列化
		objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
		//如果JSON中有新增的字段并且是实体类类中不存在的，不报错
		objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
	}
	
    /**
     * 将json转换成对象Class
     * @param src
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T>T jsonToObject(String src,Class<T> clazz){
        if(StringUtils.isEmpty(src) || clazz == null){
            return null;
        }
        try {
            return objectMapper.readValue(src,clazz);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将JSON转换成对象 TypeReference方式
     * @param src
     * @param typeReference
     * EG: 转单个对象的时候  类似new TypeReference<User>(){}
     * EG: 转list对象的时候 类似 new TypeReference<List<User>>() {}
     * EG: 转map对象jsonToObject(json, new TypeReference<Map<String,User>>() {});  
     * @param <T>
     * @return
     */
    public static <T>T jsonToObject(String src, TypeReference<T> typeReference){
        if(StringUtils.isEmpty(src) || typeReference == null){
            return null;
        }
        try {
            return objectMapper.readValue(src, typeReference);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将json转换成对象
     * @param src
     * @param collectionClass
     * @param elementClasses
     * @param <T>
     * EG:  转list对象  jsonToObject(json, List.class,User.class)
     * EG:  转map对象    jsonToObject(json, Map.class,String.class,User.class);
     * @return
     */
    public static <T>T jsonToObject(String src, Class<?> collectionClass,Class<?>... elementClasses){
        JavaType javaType = objectMapper.getTypeFactory().constructParametricType(collectionClass,elementClasses);
        try {
            return objectMapper.readValue(src,javaType);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
	
	/**
	 * 对象转JSON String 
	 * @param object
	 * @return
	 */
	public static String toJson(Object object) {
		if(object == null) {
			return null;
		}
		try {
			return objectMapper.writeValueAsString(object);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 对象转JSON String 格式化的
	 * @param object
	 * @return
	 */
	public static String toJsonPretty(Object object) {
		if(object == null) {
			return null;
		}
		try {
			return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public static void printJson(Object object) {
		if(object == null) {
			return;
		}
		System.out.println(object.getClass().getSimpleName() + "\t" +toJsonPretty(object));
	}
	
	public static void printJson(List<?> list) {
		Optional.ofNullable(list).orElse(new ArrayList<>()).forEach(o -> {
			printJson(o);
		});
	}
}
